package com.ffmpeg.util.infra.util;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Optional;

import com.ffmpeg.util.infra.config.FileConfigProperties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

/**
 * @author :wm
 * @description :文件辅助类
 */
@Component
public class FileUtil {

    private final static Logger logger = LoggerFactory.getLogger(FileUtil.class);

    private FileConfigProperties fileConfigProperties;

    @Autowired
    public void setFileConfigProperties(FileConfigProperties fileConfigProperties) {
        this.fileConfigProperties = fileConfigProperties;
    }

    /**
     * 检查来源文件
     *
     * @param sourcePath 来源文件路径
     * @return 来源文件对象
     */
    public File checkSourceFile(String sourcePath) {
        Assert.isTrue(StringUtils.isNotEmpty(sourcePath), "error.file_path.empty");
        File file = new File(sourcePath);
        Assert.isTrue(file.exists(), "error.file.not_exist");
        Assert.isTrue(!file.isDirectory(), "error.file.is_dir");
        return file;
    }

    /**
     * 通过来源文件获取目标文件路径
     *
     * @param sourceFile       来源文件
     * @param defaultTargetDir 目标文件夹路径
     * @param parentRoot 文件的父级目录
     * @return 目标文件路径
     */
    public String getTargetFilePath(File sourceFile, String defaultTargetDir, String parentRoot) {
        parentRoot = StringUtils.isEmpty(parentRoot) ? StringUtils.EMPTY : parentRoot + "\\";
        Assert.isTrue(StringUtils.isNotEmpty(sourceFile.getName()), "error.file_name.empty");
        String targetDir = StringUtils.isEmpty(defaultTargetDir) ? fileConfigProperties.getExportDirPath() : defaultTargetDir;
        targetDir += parentRoot;
        Assert.isTrue(StringUtils.isNotEmpty(targetDir), "error.target_dir.empty");
        Assert.isTrue(this.findWithCreateDir(targetDir), "error.find_or_create.file");
        Assert.isTrue(Files.isWritable(Paths.get(targetDir)), "error.not_access.write");
        return targetDir + sourceFile.getName();
    }

    /**
     * 查找目录，如果没有就新建
     *
     * @param dirPath 目录路径
     * @return 目录是否被找到或创建成功
     */
    public Boolean findWithCreateDir(String dirPath) {
        if (StringUtils.isEmpty(dirPath)) {
            logger.error("dir path is empty");
            return false;
        }
        File dir = new File(dirPath);
        if (!dir.exists()) {
            logger.info("dir {} not exist, start create", dirPath);
            if (dir.mkdirs()) {
                logger.info("dir {} created succeed", dirPath);
            } else {
                logger.error("dir {} created failed", dirPath);
                return false;
            }
        }
        if (!dir.isDirectory()) {
            logger.error("{} is not a dir", dirPath);
            return false;
        }
        return true;
    }

    /**
     * 校验文件名是否合法
     *
     * @param fileName 文件名
     */
    public void checkFileName(String fileName) {
        Assert.state(StringUtils.isNotEmpty(fileName), "error.file_name.empty");
        Assert.isTrue(StringUtils.contains(fileName, "."), "error.file_name.not_contains_point");
    }

    /**
     * 获取不带后缀的文件名
     *
     * @param fileName 文件名
     * @return 不带后缀的文件名
     */
    public String getFileNameWithoutSuffix(String fileName) {
        //校验文件名
        this.checkFileName(fileName);
        //获取不带后缀的文件名
        return fileName.replaceAll("\\.[^.]*$", "");
    }

    /**
     * 获取文件后缀
     *
     * @param fileName 文件名
     * @return 文件后缀（格式）
     */
    public String getFileSuffix(String fileName) {
        //校验文件名
        this.checkFileName(fileName);
        // 获取最后一个点号 "." 的位置
        int lastIndexOf = fileName.lastIndexOf(".");
        String suffix = null;
        // 如果文件名中有点号
        if (lastIndexOf > 0) {
            // 截取最后一个点号之后的字符串，即后缀
            suffix = fileName.substring(lastIndexOf + 1);
        }
        return suffix;
    }

}
